<?php
/**
 * 公用函数集
 * 
 * @package if
 * @subpackage util.functions
 * @since 1.0 
 */

/**
 * 标识当前文件可编译
 * 
 * @since 1.0
 */
if_compilable(__FILE__);

/**
 * 标识当前文件已经被加载
 *
 * @since 1.0
 */
define("IF_UTIL_FUNCTIONS_LOADED", 1);

/**
 * 取得选项的值
 * 
 * 函数名为Option的缩写
 *
 * - o("@db.default.host")
 * - o("@db")
 * 
 * 从1.1.0开始，可以使用第二个参数对配置进行修改
 * 
 * @param string $name 选项名
 * @return mixed
 * @since 1.0
 */
function o($name, $value = nil) {
	if (if_is_nil($value)) {
		return IConfig::opt($name);
	}
	if (substr($name, 0, 1) == "@") {
		$module = substr($name, 1, strpos($name, ".") - 1);
		if ($module) {
			$config = IConfig::module($module);
			$config->set(substr($name, strpos($name, ".") + 1), $value);
			$config->refresh();
		}
	}
	return $value;
}

/**
 * 打印数据的内容
 * 
 * 函数名为Print的缩写
 * 
 * <code>
 * p($obj);
 * p($obj1, $obj2, ...)
 * </code>
 * 
 * 从1.0.2开始，在命令行下不再显示<xmp>和</xmp>
 * 
 * @param mixed $data1 要被打印的数据
 * @since 1.0
 */
function p($data1) {
	$args = func_get_args();
	foreach ($args as $arg) {
		if (class_exists("IRequest", false) && !IRequest::singleton()->isCli()) {
			echo "<xmp>\n" . print_r($arg, true) . "\n</xmp>\n";
		}
		else {
			print_r($arg);
		}
	}
}

/**
 * 获取或设置参数对应的值
 * 
 * 函数名为conteXt的缩写
 * 
 * - x() - 取得所有参数的值
 * - x("name") - 取得参数name对应的值 
 * - x("%name") - 同x("name")
 * - x("#name") - 取得SESSION变量中name的值
 * - x("!name") - 取得Flash变量中name的值
 * - x("*name) - 取得Cookie变量中name的值
 * 
 * 从1.0.2开始起可以一次性替换字符串中的变量值
 * - px("%{name}-%{age}-*{PHPSESSID}-#{a}");
 * 
 * 从1.0.2开始起可以取得模块配置的值：
 * - x("@global.countries")
 * 但是不能修改配置的值
 * 
 * 从1.0.3开始起可以获取本地化信息
 * - x("~button_name")
 * 
 * 从1.1.0开始，可以修改配置的值：
 * - x("@global.a.b.c", "value");
 * 
 * @param string|array $name 一个或一组参数名
 * @param mixed $value 如果不为null，则将此值赋给参数
 * @return mixed
 * @since 1.0
 * @see IContext
 */
function x($name = nil, $value = nil) {
	if (if_is_nil($name)) {
		return IRequest::singleton()->params();
	}
	if (!is_string($name)) {
		if (is_array($name)) {
			$values = array();
			foreach ($name as $name2) {
				if (is_string($name2)) {
					$values[$name2] = x($name2);
				}
			}
			return $values;
		}
		return null;
	}
	
	//是否包含%{name}或#{name}
	if (strstr($name, "{")) {
		return preg_replace_callback("/([%\#\*\!~])\{(\w+)\}/s", create_function('$match', 'return x($match[1] . $match[2]);'), $name);
	}
	
	$context = IContext::singleton();
	if (!if_is_nil($value)) {
		$context[$name] = $value;
		return $value;
	}
	return $context[$name];
}

/**
 * 打印参数值
 * 
 * 相当于 p(x($name))
 *
 * @param string $name 参数名
 * @since 1.0
 */
function px($name = nil) {
	p(x($name));
}

/**
 * 获取一个DbRecord对应的查询对象
 * 
 * 函数名为Query的简写
 *
 * @param string $recordType record类型
 * @return IDbQuery
 * @since 1.0
 */
function q($recordType) {
	return IDAO::query($recordType);
}

/**
 * 取得本地化消息
 *
 * 函数为Locale的缩写
 * 
 * - l("button") - 取得button对应的消息
 * 
 * @param string $name 名称
 * @param array|null $params 参数
 * @since 1.0
 */
function l($name, array $params = null) {
	$message = IApplication::singleton()->locale()->message($name);	
	if (is_array($params)) {
		foreach ($params as $key => $value) {
			$message = str_replace("%{{$key}}", $value, $message);
		}
	}
	return $message;
}

/**
 * 取得本地化消息
 *
 * 函数为Message的缩写
 * 
 * - m("button") - 取得button对应的消息
 * 
 * 是l的同义词
 * 
 * @param string $name 名称
 * @param array|null $params 参数
 * @since 1.0
 * @see l
 */
function m($name, array $params = null) {
	return l($name, $params);
}

/**
 * 手工导入一个类
 * 
 * - import("a.b.c.MyClass")
 * - import("@rai.client.*")
 *
 * @param string $class 类名
 * @param boolean $check 是否检查类已经加载
 * @param string|null $basedir 路径
 * @return array 返回加载的文件，但如果有*通配符，则返回空数组
 * @since 1.0
 */
function import($class, $check = true, $basedir = null) {
	$class = (string)$class;
	if (preg_match("/^@(\w+)\.(.+)$/", $class, $match)) {
		$class = $match[2];
		$module = $match[1];
		if (IApplication::hasModule($module)) {
			$modules = IApplication::singleton()->modules();
			$basedir = $modules[$module];
		}
	}
	return IVM::singleton()->importClass($class, $check, $basedir);
}

/**
 * 取得File对象
 * 
 * @return IFile
 * @since 1.0.1
 */
function f($file) {
	return new IFile($file);
}

/**
 * 获取参数的值
 * 
 * 与x($name)不同的是，该函数获取的参数不会被自动过滤（通过trim和htmlspecialchars）
 * 
 * 从1.1.0开始，如果没有指定$name或$name为%，则所有参数均不过滤
 *
 * @param string $name 参数名
 * @return mixed
 * @since 1.0.3
 * @see x
 */
function xn($name = "%") {
	if ($name == "%") {
		IRequest::singleton()->noFilter("*");
	}
	else {
		IRequest::singleton()->noFilter(ltrim($name, "%"));
	}
	$value = x($name);
	IRequest::singleton()->restoreFilterParams();
	return $value;
}

?>